﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
using System.Globalization;

using Recon.Portal.Business;
using Recon.Portal.DataObjects;

namespace Recon.Portal.WebUI
{
    public partial class MatchInvoice : System.Web.UI.Page
    {
        ReconcileService objReconcileService;
        String matchType = string.Empty;
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                FillRemitterForMatching();
                GetUnmatchedLists();
            }
        }

        protected void btnManualMatch_Click(object sender, EventArgs e)
        {
            ShowPopUp(null, null, true, "Manual");
        }

        protected void btnConfirmMatches_Click(object sender, EventArgs e)
        {
            ReconcileEntity reconEntity = new ReconcileEntity();

            if (Session["MatchType"] != null && Session["MatchType"].ToString().Trim() == "Manual")
            {
                List<MatchedInvoice> matchList = new List<MatchedInvoice>();

                foreach (GridViewRow invoiceRow in grdMatchList.Rows)
                {
                    //if invoice unique id not present then ignore the row
                    Literal ltlInvoiceUniqueID = ((Literal)invoiceRow.Cells[0].FindControl("ltlInvoiceUniqueID"));
                    if (string.IsNullOrEmpty(ltlInvoiceUniqueID.Text))
                    {
                        break;
                    }

                    foreach (GridViewRow statementRow in grdMatchList.Rows)
                    {
                        //if statement unique id not present then ignore the row
                        Literal ltlStatementUniqueID = ((Literal)statementRow.Cells[1].FindControl("ltlStatementUniqueID"));
                        if (string.IsNullOrEmpty(ltlStatementUniqueID.Text))
                        {
                            break;
                        }

                        MatchedInvoice inv = new MatchedInvoice
                        {
                            InvoiceUniqueID = ltlInvoiceUniqueID.Text,
                            InvoiceNumber = invoiceRow.Cells[1].Text,
                            InvoiceDate = Convert.ToDateTime(invoiceRow.Cells[2].Text),
                            RemitterID = invoiceRow.Cells[3].Text,
                            InvoiceAmount = Convert.ToDouble(invoiceRow.Cells[4].Text),
                            InvoiceAmountToReconcile = Convert.ToDouble(invoiceRow.Cells[9].Text),
                            IsPartialInvoiceMatch=Convert.ToBoolean(((Literal)invoiceRow.Cells[1].FindControl("ltlIsPartialInvoiceMatch")).Text),
                            StatementUniqueID = ltlStatementUniqueID.Text.Replace("~CREDITNOTE~", ""),
                            ReferenceNumber = statementRow.Cells[5].Text,
                            ValueDate = Convert.ToDateTime(statementRow.Cells[6].Text),
                            Narration1 = statementRow.Cells[7].Text,
                            StatementAmount = ltlStatementUniqueID.Text.Contains("~CREDITNOTE~") ? -1 * Convert.ToDouble(statementRow.Cells[8].Text) : Convert.ToDouble(statementRow.Cells[8].Text),
                            StatementAmountToReconcile = Convert.ToDouble(statementRow.Cells[10].Text),
                            IsPartialStatementMatch = Convert.ToBoolean(((Literal)statementRow.Cells[1].FindControl("ltlIsPartialStatementMatch")).Text)
                        };
                        matchList.Add(inv);
                    }
                }

                reconEntity.MatchInvoices(matchList, "Manual", ((User)Session["CurrentUserVO"]).CustomerID, ((User)Session["CurrentUserVO"]).UserID);

                //get fresh list after database update and update UI
                GetUnmatchedLists();

                //Clear matched records from the UI
                grdMatchList.DataSource = null;
                grdMatchList.DataBind();

                ManualMatchConfirmationPopup.Hide();
            }
        }

        protected void btnCancelMatches_Click(object sender, EventArgs e)
        {
            //get fresh list after database update and update UI
            GetUnmatchedLists();

            //Clear matched records from the UI
            grdMatchList.DataSource = null;
            grdMatchList.DataBind();

            ManualMatchConfirmationPopup.Hide();
        }

        protected void btnSendToRemitter_Click(object sender, EventArgs e)
        {
            List<Invoice> dtRemitterList = new List<Invoice>();
            List<Invoice> dtInvoice = (List<Invoice>)Session["UnMatchedInvoiceList"];
            int invoiceRowNumber = 0, invoiceAdded = 0;

            foreach (GridViewRow invoiceRow in grdInvoice.Rows)
            {
                invoiceRowNumber++;
                System.Web.UI.HtmlControls.HtmlInputCheckBox chkSelect = ((System.Web.UI.HtmlControls.HtmlInputCheckBox)invoiceRow.Cells[0].FindControl("chkSelect"));
                if (chkSelect.Checked)
                {
                    invoiceAdded++;

                    Literal ltlInvoiceUniqueID = ((Literal)invoiceRow.Cells[0].FindControl("ltlInvoiceUniqueID"));

                    DateTime dt; //date time variable for correct invoice date parsing
                    Invoice invoice = new Invoice
                    {
                        InvoiceID = ltlInvoiceUniqueID.Text,
                        InvoiceNumber = invoiceRow.Cells[1].Text,
                        InvoiceDate = DateTime.TryParse(invoiceRow.Cells[2].Text.Substring(3, 2) + "/" + invoiceRow.Cells[2].Text.Substring(0, 2) + "/" + invoiceRow.Cells[2].Text.Substring(6, 4), out dt) ? Convert.ToDateTime(invoiceRow.Cells[2].Text.Substring(3, 2) + "/" + invoiceRow.Cells[2].Text.Substring(0, 2) + "/" + invoiceRow.Cells[2].Text.Substring(6, 4)) : Convert.ToDateTime(invoiceRow.Cells[2].Text.Substring(0, 2) + "/" + invoiceRow.Cells[2].Text.Substring(3, 2) + "/" + invoiceRow.Cells[2].Text.Substring(6, 4)),
                        RemitterID = invoiceRow.Cells[3].Text,
                        Amount = Convert.ToDouble(invoiceRow.Cells[4].Text)
                    };
                    dtRemitterList.Add(invoice);

                    dtInvoice.RemoveAt(invoiceRowNumber - invoiceAdded);
                }
            }

            grdRemitter.DataSource = dtRemitterList;
            grdRemitter.DataBind();

            Session["UnMatchedInvoiceList"] = dtInvoice;
            grdInvoice.DataSource = dtInvoice;
            grdInvoice.DataBind();

            RemitterConfirmationPopup.Show();
        }

        private void GetUnmatchedLists()
        {
            Lists lstEntity = new Lists();

            string strAging = Request.QueryString["Aging"];
            int minDays = 0, maxDays = 0;
            if (strAging != null)
            {
                string[] days = strAging.Split('-');
                if (days.Length == 2)
                {
                    minDays = int.Parse(days[0]);
                    maxDays = int.Parse(days[1]);
                }
                else if (days.Length == 1)
                {
                    maxDays = int.Parse(days[0]);
                }
            }
            List<Invoice> dtInvoice = lstEntity.GetUnmatchedInvoices(((User)Session["CurrentUserVO"]).CustomerID, ddlRemitter.SelectedValue.Trim(), minDays, maxDays);
            Session["UnMatchedInvoiceList"] = dtInvoice;
            grdInvoice.DataSource = dtInvoice;
            grdInvoice.DataBind();

            List<Statement> dtStatement = lstEntity.GetUnmatchedStatements(((User)Session["CurrentUserVO"]).CustomerID);
            Session["UnMatchedStatementList"] = dtStatement;
            grdStatement.DataSource = dtStatement;
            grdStatement.DataBind();

            //if any one list is empty then matching not possible, so hide buttons.
            divButtons.Visible = (dtInvoice != null && dtStatement != null);
        }

        private void FillRemitterForMatching()
        {
            //clear existing list
            ddlRemitter.Items.Clear();

            RemitterEntity lstEntity = new RemitterEntity();
            List<Remitter> remitterList = lstEntity.GetRemitterIdForMatchingCriteria(((User)Session["CurrentUserVO"]).CustomerID);
            //StringBuilder listRemitterId = new StringBuilder();
            ////listRemitterId = null;

            if (remitterList != null && remitterList.Count<Remitter>() > 0)
            {
                ddlRemitter.Items.Add(new ListItem("All Remitters", "0"));
                foreach (Remitter remitter in remitterList)
                {
                    ddlRemitter.Items.Add(new ListItem(remitter.RemitterName, remitter.RemitterID));
                    //listRemitterId.Append("'"+ remitter.RemitterID +"',");
                }
                //listRemitterId.Remove(listRemitterId.Length - 1, 1);
                //ddlRemitter.Items.Add(new ListItem("Select All Remitter", listRemitterId.ToString()));
                ddlRemitter.SelectedIndex = 0;
            }
        }

        protected void ddlRemitter_SelectedIndexChanged(object sender, EventArgs e)
        {
            GetUnmatchedLists();
        }

        private List<string> ShowPopUp(List<Invoice> dtInvoiceUnMatch, List<Statement> dtStatementUnMatch, bool isManual, string matchType)
        {
            List<string> successMatchType = new List<string>();
            bool isMatched = false;
            List<MatchedInvoice> matchList = new List<MatchedInvoice>();
            ReconcileEntity reconEntity = new ReconcileEntity();

            if (matchType == "Manual")
            {
                List<Invoice> dtInvoice = (List<Invoice>)Session["UnMatchedInvoiceList"];
                List<Statement> dtStatement = (List<Statement>)Session["UnMatchedStatementList"];
                int invoiceRowNumber = 0, statementRowNumber = 0, invoiceAdded = 0, statementAdded = 0;
                double totalInvoiceAmount = 0.00, totalStatementAmount = 0.00;

                //list of invoices
                foreach (GridViewRow invoiceRow in grdInvoice.Rows)
                {
                    invoiceRowNumber++;
                    System.Web.UI.HtmlControls.HtmlInputCheckBox chkSelect = ((System.Web.UI.HtmlControls.HtmlInputCheckBox)invoiceRow.Cells[0].FindControl("chkSelect"));
                    if (chkSelect.Checked)
                    {
                        Literal ltlInvoiceUniqueID = ((Literal)invoiceRow.Cells[0].FindControl("ltlInvoiceUniqueID"));

                        if (invoiceRow.BackColor != System.Drawing.Color.Cyan)
                        {
                            invoiceAdded++;

                            if (invoiceAdded <= statementAdded)
                            {
                                MatchedInvoice match = matchList[invoiceAdded - 1];
                                match.InvoiceUniqueID = ltlInvoiceUniqueID.Text;
                                match.InvoiceNumber = invoiceRow.Cells[1].Text;
                                match.InvoiceDate = Convert.ToDateTime(invoiceRow.Cells[2].Text);
                                match.RemitterName = invoiceRow.Cells[3].Text;
                                match.InvoiceAmount = Convert.ToDouble(invoiceRow.Cells[4].Text);
                                match.InvoiceAmountToReconcile = Convert.ToDouble(invoiceRow.Cells[6].Text);
                                match.IsPartialStatementMatch = false;
                                totalInvoiceAmount += match.InvoiceAmountToReconcile;
                            }
                            else
                            {
                                MatchedInvoice inv = new MatchedInvoice
                                {
                                    InvoiceUniqueID = ltlInvoiceUniqueID.Text,
                                    InvoiceNumber = invoiceRow.Cells[1].Text,
                                    InvoiceDate = Convert.ToDateTime(invoiceRow.Cells[2].Text),
                                    RemitterName = invoiceRow.Cells[3].Text,
                                    InvoiceAmount = Convert.ToDouble(invoiceRow.Cells[4].Text),
                                    InvoiceAmountToReconcile = Convert.ToDouble(invoiceRow.Cells[6].Text),
                                    IsPartialInvoiceMatch = false
                                };
                                matchList.Add(inv);
                                totalInvoiceAmount += inv.InvoiceAmountToReconcile;
                            }
                        }
                        else
                        {
                            statementAdded++;

                            if (statementAdded <= invoiceAdded)
                            {
                                MatchedInvoice match = matchList[statementAdded - 1];
                                match.StatementUniqueID = ltlInvoiceUniqueID.Text + "~CREDITNOTE~";
                                match.ReferenceNumber = invoiceRow.Cells[1].Text;
                                match.ValueDate = Convert.ToDateTime(invoiceRow.Cells[2].Text);
                                match.Narration1 = invoiceRow.Cells[3].Text;
                                match.StatementAmount = Convert.ToDouble(invoiceRow.Cells[4].Text);
                                match.StatementAmountToReconcile = Convert.ToDouble(invoiceRow.Cells[6].Text);
                                match.IsPartialStatementMatch = false;
                                totalStatementAmount += match.StatementAmountToReconcile;
                            }
                            else
                            {
                                MatchedInvoice inv = new MatchedInvoice
                                {
                                    StatementUniqueID = ltlInvoiceUniqueID.Text + "~CREDITNOTE~",
                                    ReferenceNumber = invoiceRow.Cells[1].Text,
                                    ValueDate = Convert.ToDateTime(invoiceRow.Cells[2].Text),
                                    Narration1 = invoiceRow.Cells[3].Text,
                                    StatementAmount = Convert.ToDouble(invoiceRow.Cells[4].Text),
                                    StatementAmountToReconcile = Convert.ToDouble(invoiceRow.Cells[6].Text),
                                    IsPartialStatementMatch = false
                                };
                                matchList.Add(inv);
                                totalStatementAmount += inv.StatementAmountToReconcile;
                            }
                        }

                        dtInvoice.RemoveAt(invoiceRowNumber - invoiceAdded - statementAdded);
                    }
                }

                //statements may have been added if credit notes present in selected invoice list, so set statementRowNumber to begin with the same value as statementAdded for removal of correct row from in-memory list
                statementRowNumber = statementAdded;
                //list of statements
                foreach (GridViewRow statementRow in grdStatement.Rows)
                {
                    statementRowNumber++;
                    System.Web.UI.HtmlControls.HtmlInputCheckBox chkSelect = ((System.Web.UI.HtmlControls.HtmlInputCheckBox)statementRow.Cells[0].FindControl("chkSelect"));
                    if (chkSelect.Checked)
                    {
                        statementAdded++;

                        Literal ltlStatementUniqueID = ((Literal)statementRow.Cells[0].FindControl("ltlStatementUniqueID"));

                        if (statementAdded <= invoiceAdded)
                        {
                            MatchedInvoice match = matchList[statementAdded - 1];
                            match.StatementUniqueID = ltlStatementUniqueID.Text;
                            match.ReferenceNumber = statementRow.Cells[1].Text;
                            match.ValueDate = Convert.ToDateTime(statementRow.Cells[2].Text);
                            match.Narration1 = statementRow.Cells[3].Text;
                            match.StatementAmount = Convert.ToDouble(statementRow.Cells[4].Text);
                            match.StatementAmountToReconcile = Convert.ToDouble(statementRow.Cells[6].Text);
                            match.IsPartialStatementMatch = false;
                            totalStatementAmount += match.StatementAmountToReconcile;
                        }
                        else
                        {
                            MatchedInvoice match = new MatchedInvoice
                                {
                                    StatementUniqueID = ltlStatementUniqueID.Text,
                                    ReferenceNumber = statementRow.Cells[1].Text,
                                    ValueDate = Convert.ToDateTime(statementRow.Cells[2].Text),
                                    Narration1 = statementRow.Cells[3].Text,
                                    StatementAmount = Convert.ToDouble(statementRow.Cells[4].Text),
                                    StatementAmountToReconcile = Convert.ToDouble(statementRow.Cells[6].Text),
                                    IsPartialStatementMatch = false
                                };
                            matchList.Add(match);
                            totalStatementAmount += match.StatementAmountToReconcile;
                        }

                        dtStatement.RemoveAt(statementRowNumber - statementAdded);
                    }
                }

                //show matched list on popup
                if (matchList.Count<MatchedInvoice>() > 0)
                {
                    //calculate amount to reconcile - if both total match then no change in AmountToReconcile
                    //else subtract the difference against the last item that's on the higher side
                    if (totalInvoiceAmount > totalStatementAmount)
                    {
                        MatchedInvoice lastMatch = matchList.Last((m) => m.InvoiceAmountToReconcile > 0);
                        lastMatch.InvoiceAmountToReconcile -= totalInvoiceAmount - totalStatementAmount;
                        lastMatch.IsPartialInvoiceMatch = true;
                    }
                    else if(totalInvoiceAmount < totalStatementAmount)
                    {
                        MatchedInvoice lastMatch = matchList.Last((m) => m.StatementAmountToReconcile > 0);
                        lastMatch.StatementAmountToReconcile -= totalStatementAmount - totalInvoiceAmount;
                        lastMatch.IsPartialStatementMatch = true;
                    }

                    Session["MatchType"] = matchType;
                    grdMatchList.DataSource = matchList;
                    grdMatchList.DataBind();
                    btnConfirmMatches.Visible = true;
                    btnCancelMatches.Text = "Cancel Matches";
                }
                else
                {
                    grdMatchList.DataSource = null;
                    grdMatchList.DataBind();
                    btnConfirmMatches.Visible = false;
                    btnCancelMatches.Text = "Close";
                }

                Session["UnMatchedInvoiceList"] = dtInvoice;
                grdInvoice.DataSource = dtInvoice;
                grdInvoice.DataBind();

                Session["UnMatchedStatementList"] = dtStatement;
                grdStatement.DataSource = dtStatement;
                grdStatement.DataBind();

                ManualMatchConfirmationPopup.Show();
            }
            else if (matchType == "Amount")
            {
                int invoiceRowNumber = 0, statementRowNumber = 0, invoiceAdded = 0, statementAdded = 0;
                for (int invCount = 0; invCount < dtInvoiceUnMatch.Count<Invoice>(); invCount++)
                {
                    double invoiceAmt;
                    invoiceRowNumber++;
                    //check for previous row matched or not.
                    if (!isMatched)
                    {
                        //if not matched then continue
                        invoiceAmt = Convert.ToDouble(dtInvoiceUnMatch[invCount].Amount);
                        //current count
                        invoiceRowNumber = invCount;
                    }
                    else
                    {
                        //if matched then start from "0".
                        invoiceAmt = Convert.ToDouble(dtInvoiceUnMatch[0].Amount);
                        //reset  count to "0"
                        invoiceRowNumber = 0;
                    }

                    for (int stmCount = 0; stmCount < dtStatementUnMatch.Count<Statement>(); stmCount++)
                    {
                        statementRowNumber++;
                        double stmntAmt = Convert.ToDouble(dtStatementUnMatch[stmCount].amount);

                        if (invoiceAmt == stmntAmt)
                        {
                            invoiceAdded++;
                            statementAdded++;
                            Invoice matchedInvoiceRow = dtInvoiceUnMatch[invoiceRowNumber];
                            Statement matchedStmtRow = dtStatementUnMatch[stmCount];

                            MatchedInvoice match = new MatchedInvoice
                            {
                                InvoiceUniqueID = matchedInvoiceRow.InvoiceID,
                                InvoiceNumber = matchedInvoiceRow.InvoiceNumber,
                                InvoiceDate = matchedInvoiceRow.InvoiceDate,
                                RemitterID = matchedInvoiceRow.RemitterID,
                                InvoiceAmount = matchedInvoiceRow.Amount,
                                StatementUniqueID = matchedStmtRow.StatementID,
                                ReferenceNumber = matchedStmtRow.referenceNumber,
                                ValueDate = matchedStmtRow.valueDate,
                                Narration1 = matchedStmtRow.narration1,
                                StatementAmount = matchedStmtRow.amount
                            };
                            matchList.Add(match);

                            dtInvoiceUnMatch.RemoveAt(invoiceRowNumber);
                            dtStatementUnMatch.RemoveAt(stmCount);

                            //if matched then make flag true and invcount reset to 0 and break current for loop
                            isMatched = true;
                            invCount = -1;
                            break;
                        }
                        //if not matched then make flag false
                        isMatched = false;
                    }
                }

                if (matchList.Count<MatchedInvoice>() > 0)
                {
                    Session["AutoAmountMatchConfirmPopUp"] = matchList;
                    Session["MatchType"] = matchType;
                }
                else
                {
                    Session["AutoAmountMatchConfirmPopUp"] = null;
                }

                Session["UnMatchedInvoiceList"] = dtInvoiceUnMatch;

                Session["UnMatchedStatementList"] = dtStatementUnMatch;

                if (Session["MatchType"] != null && Session["MatchType"].ToString().Trim() == "Amount")
                {
                    reconEntity.MatchInvoices(matchList, "Amount", ((User)Session["CurrentUserVO"]).CustomerID, ((User)Session["CurrentUserVO"]).UserID);
                    lblAutoMatch.Text = "Auto Match has done for Amount!";
                    btnAutoMatchClickPopup.Show();
                    successMatchType.Add("Amount");
                    //get fresh list after database update and update UI
                    GetUnmatchedLists();
                }
            }
            else if (matchType == "Amount&Ref")
            {
                int invoiceRowNumber = 0, statementRowNumber = 0, invoiceAdded = 0, statementAdded = 0;
                for (int invCount = 0; invCount < dtInvoiceUnMatch.Count<Invoice>(); invCount++)
                {
                    double invoiceAmt;
                    String InvoiceNumber;
                    invoiceRowNumber++;
                    //check for previous row matched or not.
                    if (!isMatched)
                    {
                        //if not matched then continue
                        invoiceAmt = Convert.ToDouble(dtInvoiceUnMatch[invCount].Amount);
                        InvoiceNumber = dtInvoiceUnMatch[invCount].InvoiceNumber;
                        //current count
                        invoiceRowNumber = invCount;
                    }
                    else
                    {
                        //if matched then start from "0".
                        invoiceAmt = Convert.ToDouble(dtInvoiceUnMatch[0].Amount);
                        InvoiceNumber = dtInvoiceUnMatch[0].InvoiceNumber;
                        //reset  count to "0"
                        invoiceRowNumber = 0;
                    }

                    for (int stmCount = 0; stmCount < dtStatementUnMatch.Count<Statement>(); stmCount++)
                    {
                        statementRowNumber++;
                        double stmntAmt = Convert.ToDouble(dtStatementUnMatch[stmCount].amount);
                        String stmtInvoiceNumber = dtStatementUnMatch[stmCount].referenceNumber;

                        if (invoiceAmt == stmntAmt && (InvoiceNumber == stmtInvoiceNumber))
                        {
                            invoiceAdded++;
                            statementAdded++;
                            Invoice matchedInvoiceRow = dtInvoiceUnMatch[invoiceRowNumber];
                            Statement matchedStmtRow = dtStatementUnMatch[stmCount];

                            MatchedInvoice match = new MatchedInvoice
                            {
                                InvoiceUniqueID = matchedInvoiceRow.InvoiceID,
                                InvoiceNumber = matchedInvoiceRow.InvoiceNumber,
                                InvoiceDate = matchedInvoiceRow.InvoiceDate,
                                RemitterID = matchedInvoiceRow.RemitterID,
                                InvoiceAmount = matchedInvoiceRow.Amount,
                                StatementUniqueID = matchedStmtRow.StatementID,
                                ReferenceNumber = matchedStmtRow.referenceNumber,
                                ValueDate = matchedStmtRow.valueDate,
                                Narration1 = matchedStmtRow.narration1,
                                StatementAmount = matchedStmtRow.amount
                            };
                            matchList.Add(match);

                            dtInvoiceUnMatch.RemoveAt(invoiceRowNumber);
                            dtStatementUnMatch.RemoveAt(stmCount);
                            //if matched then make flag true and invcount reset to 0 and break current for loop
                            isMatched = true;
                            invCount = -1;
                            break;
                        }
                        //if not matched then make flag false
                        isMatched = false;
                    }
                }

                if (matchList.Count<MatchedInvoice>() > 0)
                {
                    Session["AutoAmountMatchConfirmPopUp"] = matchList;
                    Session["MatchType"] = matchType;
                }
                else
                {
                    Session["AutoAmountMatchConfirmPopUp"] = null;
                }

                Session["UnMatchedInvoiceList"] = dtInvoiceUnMatch;

                Session["UnMatchedStatementList"] = dtStatementUnMatch;

                if (Session["MatchType"] != null && Session["MatchType"].ToString().Trim() == "Amount&Ref")
                {
                    reconEntity.MatchInvoices(matchList, "Amount&Ref", ((User)Session["CurrentUserVO"]).CustomerID, ((User)Session["CurrentUserVO"]).UserID);
                    lblAutoMatch.Text = "Auto Match has done for Referance!";
                    btnAutoMatchClickPopup.Show();
                    successMatchType.Add("Referance");
                    //get fresh list after database update and update UI
                    GetUnmatchedLists();
                }
            }
            else if (matchType == "Discount")
            {
                int invoiceRowNumber = 0, statementRowNumber = 0, invoiceAdded = 0, statementAdded = 0;
                for (int invCount = 0; invCount < dtInvoiceUnMatch.Count<Invoice>(); invCount++)
                {
                    double invoiceAmt;
                    string remId;
                    DateTime invoiceDate;
                    invoiceRowNumber++;
                    //check for previous row matched or not.
                    if (!isMatched)
                    {
                        //if not matched then continue
                        invoiceAmt = dtInvoiceUnMatch[invCount].Amount;
                        remId = dtInvoiceUnMatch[invCount].RemitterID;
                        invoiceDate = dtInvoiceUnMatch[invCount].InvoiceDate;
                        //current count
                        invoiceRowNumber = invCount;
                    }
                    else
                    {
                        //if matched then start from "0".
                        invoiceAmt = dtInvoiceUnMatch[0].Amount;
                        remId = dtInvoiceUnMatch[0].RemitterID;
                        invoiceDate = dtInvoiceUnMatch[0].InvoiceDate;
                        //reset  count to "0"
                        invoiceRowNumber = 0;
                    }

                    for (int stmCount = 0; stmCount < dtStatementUnMatch.Count<Statement>(); stmCount++)
                    {
                        statementRowNumber++;
                        double stmntAmt = dtStatementUnMatch[stmCount].amount;
                        DateTime statementDate = dtStatementUnMatch[stmCount].valueDate;

                        double discountPerc = 0.00;
                        double discountAmount = 0.00;

                        objReconcileService = new ReconcileService();
                        discountPerc = objReconcileService.getDiscountDetails(((User)Session["CurrentUserVO"]).CustomerID, remId, invoiceDate, statementDate);

                        if (discountPerc > 0.0)
                        {
                            discountAmount = invoiceAmt * (discountPerc / 100);
                            if (invoiceAmt - discountAmount == stmntAmt)
                            {
                                invoiceAdded++;
                                statementAdded++;
                                Invoice matchedInvoiceRow = dtInvoiceUnMatch[invoiceRowNumber];
                                Statement matchedStmtRow = dtStatementUnMatch[stmCount];

                                MatchedInvoice match = new MatchedInvoice
                                {
                                    InvoiceUniqueID = matchedInvoiceRow.InvoiceID,
                                    InvoiceNumber = matchedInvoiceRow.InvoiceNumber,
                                    InvoiceDate = matchedInvoiceRow.InvoiceDate,
                                    RemitterID = matchedInvoiceRow.RemitterID,
                                    InvoiceAmount = matchedInvoiceRow.Amount,
                                    StatementUniqueID = matchedStmtRow.StatementID,
                                    ReferenceNumber = matchedStmtRow.referenceNumber,
                                    ValueDate = matchedStmtRow.valueDate,
                                    Narration1 = matchedStmtRow.narration1,
                                    StatementAmount = matchedStmtRow.amount
                                };
                                matchList.Add(match);

                                dtInvoiceUnMatch.RemoveAt(invoiceRowNumber);
                                dtStatementUnMatch.RemoveAt(stmCount);

                                //if matched then make flag true and invcount reset to 0 and break current for loop
                                isMatched = true;
                                invCount = -1;
                                break;
                            }
                            //if not matched then make flag false
                            isMatched = false;
                        }
                        //if not matched then make flag false
                        isMatched = false;
                    }
                }

                if (matchList.Count<MatchedInvoice>() > 0)
                {
                    Session["AutoAmountMatchConfirmPopUp"] = matchList;
                    Session["MatchType"] = matchType;
                }
                else
                {
                    Session["AutoAmountMatchConfirmPopUp"] = null;
                }

                Session["UnMatchedInvoiceList"] = dtInvoiceUnMatch;

                Session["UnMatchedStatementList"] = dtStatementUnMatch;

                if (Session["MatchType"] != null && Session["MatchType"].ToString().Trim() == "Discount")
                {
                    reconEntity.MatchInvoices(matchList, "Discount", ((User)Session["CurrentUserVO"]).CustomerID, ((User)Session["CurrentUserVO"]).UserID);
                    lblAutoMatch.Text = "Auto Match has done for Discount!";
                    btnAutoMatchClickPopup.Show();
                    successMatchType.Add("Discount");
                    //get fresh list after database update and update UI
                    GetUnmatchedLists();
                }
            }
            else if (matchType == "Penalty")
            {
                int invoiceRowNumber = 0, statementRowNumber = 0, invoiceAdded = 0, statementAdded = 0;
                for (int invCount = 0; invCount < dtInvoiceUnMatch.Count<Invoice>(); invCount++)
                {
                    double invoiceAmt;
                    string remId;
                    DateTime invoiceDate;
                    invoiceRowNumber++;
                    //check for previous row matched or not.
                    if (!isMatched)
                    {
                        //if not matched then continue
                        invoiceAmt = dtInvoiceUnMatch[invCount].Amount;
                        remId = dtInvoiceUnMatch[invCount].RemitterID;
                        invoiceDate = dtInvoiceUnMatch[invCount].InvoiceDate;
                        invoiceRowNumber = invCount;
                    }
                    else
                    {
                        //if matched then start from "0".
                        invoiceAmt = dtInvoiceUnMatch[0].Amount;
                        remId = dtInvoiceUnMatch[0].RemitterID;
                        invoiceDate = dtInvoiceUnMatch[0].InvoiceDate;
                        invoiceRowNumber = 0;
                    }

                    for (int stmCount = 0; stmCount < dtStatementUnMatch.Count<Statement>(); stmCount++)
                    {
                        statementRowNumber++;
                        double stmntAmt = dtStatementUnMatch[stmCount].amount;
                        DateTime statementDate = dtStatementUnMatch[stmCount].statementDate;
                        double penaltyPerc = 0.00;
                        double penaltyAmount = 0.00;

                        objReconcileService = new ReconcileService();
                        penaltyPerc = objReconcileService.getPenaltyDetails(((User)Session["CurrentUserVO"]).CustomerID, remId, invoiceDate, statementDate);

                        if (penaltyPerc > 0.0)
                        {
                            penaltyAmount = invoiceAmt * (penaltyPerc / 100);

                            if (((invoiceAmt + (penaltyAmount)) == stmntAmt))
                            {
                                invoiceAdded++;
                                statementAdded++;
                                Invoice matchedInvoiceRow = dtInvoiceUnMatch[invoiceRowNumber];
                                Statement matchedStmtRow = dtStatementUnMatch[stmCount];

                                MatchedInvoice match = new MatchedInvoice
                                {
                                    InvoiceUniqueID = matchedInvoiceRow.InvoiceID,
                                    InvoiceNumber = matchedInvoiceRow.InvoiceNumber,
                                    InvoiceDate = matchedInvoiceRow.InvoiceDate,
                                    RemitterID = matchedInvoiceRow.RemitterID,
                                    InvoiceAmount = matchedInvoiceRow.Amount,
                                    StatementUniqueID = matchedStmtRow.StatementID,
                                    ReferenceNumber = matchedStmtRow.referenceNumber,
                                    ValueDate = matchedStmtRow.valueDate,
                                    Narration1 = matchedStmtRow.narration1,
                                    StatementAmount = matchedStmtRow.amount
                                };
                                matchList.Add(match);

                                dtInvoiceUnMatch.RemoveAt(invoiceRowNumber);
                                dtStatementUnMatch.RemoveAt(stmCount);

                                //if matched then make flag true and invcount reset to 0 and break current for loop
                                isMatched = true;
                                invCount = -1;
                                break;
                            }
                            //if not matched then make flag false
                            isMatched = false;
                        }
                        //if not matched then make flag false
                        isMatched = false;
                    }
                }

                if (matchList.Count<MatchedInvoice>() > 0)
                {
                    Session["AutoAmountMatchConfirmPopUp"] = matchList;
                    Session["MatchType"] = matchType;
                }
                else
                {
                    Session["AutoAmountMatchConfirmPopUp"] = null;
                }

                Session["UnMatchedInvoiceList"] = dtInvoiceUnMatch;

                Session["UnMatchedStatementList"] = dtStatementUnMatch;

                if (Session["MatchType"] != null && Session["MatchType"].ToString().Trim() == "Penalty")
                {
                    reconEntity.MatchInvoices(matchList, "Penalty", ((User)Session["CurrentUserVO"]).CustomerID, ((User)Session["CurrentUserVO"]).UserID);
                    lblAutoMatch.Text = "Auto Match has done for Penalty!";
                    btnAutoMatchClickPopup.Show();
                    successMatchType.Add("Penalty");
                    //get fresh list after database update and update UI
                    GetUnmatchedLists();
                }
            }
            return successMatchType;
        }

        protected void grdInvoice_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowIndex > -1)
            {
                double value = 0.00;
                if (e.Row.Cells[4].Text != "" && e.Row.Cells[4].Text != "&nbsp;")
                {
                    value = Convert.ToDouble(e.Row.Cells[4].Text);
                    if (value < 0)
                    {
                        e.Row.BackColor = System.Drawing.Color.Cyan;
                        value *= -1;
                    }
                    e.Row.Cells[4].Text = value.ToString("#,#.00", CultureInfo.InvariantCulture);
                    e.Row.Cells[4].HorizontalAlign = HorizontalAlign.Right;
                }
                else
                {
                    e.Row.Cells[4].Text = "0.00";
                }
                if (e.Row.Cells[5].Text != "" && e.Row.Cells[5].Text != "&nbsp;")
                {
                    value = Convert.ToDouble(e.Row.Cells[5].Text);
                    if (value < 0)
                    {
                        value *= -1;
                    }
                    e.Row.Cells[5].Text = value.ToString("#,0.00", CultureInfo.InvariantCulture);
                    e.Row.Cells[5].HorizontalAlign = HorizontalAlign.Right;
                }
                else
                {
                    e.Row.Cells[5].Text = "0.00";
                }
                if (e.Row.Cells[6].Text != "" && e.Row.Cells[6].Text != "&nbsp;")
                {
                    value = Convert.ToDouble(e.Row.Cells[6].Text);
                    if (value < 0)
                    {
                        value *= -1;
                    }
                    e.Row.Cells[6].Text = value.ToString("#,0.00", CultureInfo.InvariantCulture);
                    e.Row.Cells[6].HorizontalAlign = HorizontalAlign.Right;
                }
                else
                {
                    e.Row.Cells[6].Text = "0.00";
                }
                DateTime dt;
                if (e.Row.Cells[2].Text != "" && e.Row.Cells[2].Text != "&nbsp;")
                {
                    dt = Convert.ToDateTime(e.Row.Cells[2].Text);
                    e.Row.Cells[2].Text = dt.ToString("dd-MM-yyyy");
                    e.Row.Cells[2].HorizontalAlign = HorizontalAlign.Center;
                }
                else
                {
                    e.Row.Cells[2].Text = "";
                }
            }
        }

        protected void grdStatement_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowIndex > -1)
            {
                double value = 0.00;
                if (e.Row.Cells[4].Text != "" && e.Row.Cells[4].Text != "&nbsp;")
                {
                    value = Convert.ToDouble(e.Row.Cells[4].Text);
                    if (value < 0)
                    {
                        e.Row.BackColor = System.Drawing.Color.Cyan;
                        value *= -1;
                    }
                    e.Row.Cells[4].Text = value.ToString("#,#.00", CultureInfo.InvariantCulture);
                    e.Row.Cells[4].HorizontalAlign = HorizontalAlign.Right;
                }
                else
                {
                    e.Row.Cells[4].Text = "0.00";
                }
                if (e.Row.Cells[5].Text != "" && e.Row.Cells[5].Text != "&nbsp;")
                {
                    value = Convert.ToDouble(e.Row.Cells[5].Text);
                    if (value < 0)
                    {
                        value *= -1;
                    }
                    e.Row.Cells[5].Text = value.ToString("#,0.00", CultureInfo.InvariantCulture);
                    e.Row.Cells[5].HorizontalAlign = HorizontalAlign.Right;
                }
                else
                {
                    e.Row.Cells[5].Text = "0.00";
                }
                if (e.Row.Cells[6].Text != "" && e.Row.Cells[6].Text != "&nbsp;")
                {
                    value = Convert.ToDouble(e.Row.Cells[6].Text);
                    if (value < 0)
                    {
                        value *= -1;
                    }
                    e.Row.Cells[6].Text = value.ToString("#,0.00", CultureInfo.InvariantCulture);
                    e.Row.Cells[6].HorizontalAlign = HorizontalAlign.Right;
                }
                else
                {
                    e.Row.Cells[6].Text = "0.00";
                }
                DateTime dt;
                if (e.Row.Cells[2].Text != "" && e.Row.Cells[2].Text != "&nbsp;")
                {
                    dt = Convert.ToDateTime(e.Row.Cells[2].Text);
                    e.Row.Cells[2].Text = dt.ToString("dd-MM-yyyy");
                    e.Row.Cells[2].HorizontalAlign = HorizontalAlign.Center;
                }
                else
                {
                    e.Row.Cells[2].Text = "";
                }
            }
        }

        protected void grdMatchList_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowIndex > -1)
            {
                DateTime dt;
                if (e.Row.Cells[2].Text != "" && e.Row.Cells[2].Text != "&nbsp;")
                {
                    dt = Convert.ToDateTime(e.Row.Cells[2].Text);
                    e.Row.Cells[2].Text = dt.ToString("dd-MM-yyyy");
                    e.Row.Cells[2].HorizontalAlign = HorizontalAlign.Center;
                }
                else
                {
                    e.Row.Cells[2].Text = "";
                }
                if (e.Row.Cells[6].Text != "" && e.Row.Cells[6].Text != "&nbsp;")
                {
                    dt = Convert.ToDateTime(e.Row.Cells[6].Text);
                    e.Row.Cells[6].Text = dt.ToString("dd-MM-yyyy");
                    e.Row.Cells[6].HorizontalAlign = HorizontalAlign.Center;
                }
                else
                {
                    e.Row.Cells[6].Text = "";
                }

                double value = 0.00;
                //INVOICE amount
                if (e.Row.Cells[4].Text != "" && e.Row.Cells[4].Text != "&nbsp;")
                {
                    value = Convert.ToDouble(e.Row.Cells[4].Text);
                    e.Row.Cells[4].Text = value.ToString("#,#.00", CultureInfo.InvariantCulture);
                    e.Row.Cells[4].HorizontalAlign = HorizontalAlign.Right;
                }
                else
                {
                    e.Row.Cells[4].Text = "0.00";
                }
                //statement/credit note amount
                if (e.Row.Cells[8].Text != "" && e.Row.Cells[8].Text != "&nbsp;")
                {
                    value = Convert.ToDouble(e.Row.Cells[8].Text);
                    e.Row.Cells[8].Text = value.ToString("#,#.00", CultureInfo.InvariantCulture);
                    e.Row.Cells[8].HorizontalAlign = HorizontalAlign.Right;
                }
                else
                {
                    e.Row.Cells[8].Text = "0.00";
                }
                //invoice amount to reconcile
                if (e.Row.Cells[9].Text != "" && e.Row.Cells[9].Text != "&nbsp;")
                {
                    value = Convert.ToDouble(e.Row.Cells[9].Text);
                    e.Row.Cells[9].Text = value.ToString("#,#.00", CultureInfo.InvariantCulture);
                    e.Row.Cells[9].HorizontalAlign = HorizontalAlign.Right;
                }
                else
                {
                    e.Row.Cells[9].Text = "0.00";
                }
                //statement amount to reconcile
                if (e.Row.Cells[10].Text != "" && e.Row.Cells[10].Text != "&nbsp;")
                {
                    value = Convert.ToDouble(e.Row.Cells[10].Text);
                    e.Row.Cells[10].Text = value.ToString("#,#.00", CultureInfo.InvariantCulture);
                    e.Row.Cells[10].HorizontalAlign = HorizontalAlign.Right;
                }
                else
                {
                    e.Row.Cells[10].Text = "0.00";
                }
            }
        }

        protected void grdRemitter_RowDataBound(object sender, GridViewRowEventArgs e)
        {

        }

        protected void btnConfirmRemitter_Click(object sender, EventArgs e)
        {
            List<Invoice> dtRemitterList = new List<Invoice>();

            foreach (GridViewRow invoiceRow in grdRemitter.Rows)
            {
                Literal ltlInvoiceUniqueID = ((Literal)invoiceRow.Cells[0].FindControl("ltlInvoiceUniqueID"));

                Invoice inv = new Invoice
                {
                    InvoiceID = ltlInvoiceUniqueID.Text,
                    CustomerID = ((User)Session["CurrentUserVO"]).CustomerID,
                    InvoiceNumber = invoiceRow.Cells[1].Text,
                    InvoiceDate = Convert.ToDateTime(invoiceRow.Cells[2].Text),
                    RemitterID = invoiceRow.Cells[3].Text,
                    Amount = Convert.ToDouble(invoiceRow.Cells[4].Text)
                };
                dtRemitterList.Add(inv);
            }

            ReconcileEntity db = new ReconcileEntity();
            db.SendInvoicesToRemitter(dtRemitterList);

            //get fresh list after database update and update UI
            GetUnmatchedLists();

            //Clear sent records from the UI
            grdRemitter.DataSource = null;
            grdRemitter.DataBind();

            RemitterConfirmationPopup.Hide();
        }

        protected void btnCancelRemitter_Click(object sender, EventArgs e)
        {
            //get fresh list after database update and update UI
            GetUnmatchedLists();

            //Clear records marked for sending from the UI
            grdRemitter.DataSource = null;
            grdRemitter.DataBind();

            RemitterConfirmationPopup.Hide();
        }

        protected void btnAutoMatching_Click(object sender, EventArgs e)
        {
            List<List<string>> successMatchType = new List<List<string>>();
            string TYPES = string.Empty;
            //Call Auto sequncing function for match
            successMatchType = AutoSequncing();
            if (successMatchType != null)
            {
                if (successMatchType.Count > 0)
                {
                    foreach (List<string> items in successMatchType)
                    {
                        foreach (string item in items)
                        {
                            TYPES = TYPES + item.ToString() + ", ";
                        }
                    }
                    if (TYPES != "")
                    {
                        TYPES = TYPES.Remove(TYPES.Length - 2, 1) + "!";
                        lblAutoMatch.Text = "Auto Match done for " + TYPES;
                        btnAutoMatchClickPopup.Show();
                    }
                    else
                    {
                        lblAutoMatch.Text = "No records found for Auto Match!";
                        btnAutoMatchClickPopup.Show();
                    }


                }
                else
                {
                    lblAutoMatch.Text = "No records found for Auto Match!";
                    btnAutoMatchClickPopup.Show();
                }
            }
            else
            {
                lblAutoMatch.Text = "No records found for Auto Match!";
                btnAutoMatchClickPopup.Show();
            }
        }
        private enum AutoSequence
        {
            Amount = 1,
            AmountAndRef = 2,
            Discount = 3,
            Penalty = 4

        }

        protected void btnAutoMatchok_Click(object sender, EventArgs e)
        {
            btnAutoMatchClickPopup.Hide();
        }
        private List<List<string>> AutoSequncing()
        {
            AutoMatching db = new AutoMatching();
            List<string> successMatchType = new List<string>();
            List<List<string>> successMatchTypeList = new List<List<string>>();
            Lists lstAuto = new Lists();
            List<string> dtAutoSequnceName = lstAuto.GetAutoSequenceForMatchInvoice(((User)Session["CurrentUserVO"]).CustomerID, ddlRemitter.SelectedValue.Trim());
            if (dtAutoSequnceName != null && dtAutoSequnceName.Count<string>() > 0)
            {
                foreach (string sequenceName in dtAutoSequnceName)
                {
                    List<Invoice> invoiceLst = (List<Invoice>)Session["UnMatchedInvoiceList"];
                    List<Statement> statementLst = (List<Statement>)Session["UnMatchedStatementList"];
                    switch (sequenceName)
                    {
                        case "Amount":
                            successMatchType = ShowPopUp(invoiceLst, statementLst, false, "Amount");
                            successMatchTypeList.Add(successMatchType);
                            break;
                        case "AmountAndRef":
                            successMatchType = ShowPopUp(invoiceLst, statementLst, false, "Amount&Ref");
                            successMatchTypeList.Add(successMatchType);
                            break;
                        case "Discount":
                            successMatchType = ShowPopUp(invoiceLst, statementLst, false, "Discount");
                            successMatchTypeList.Add(successMatchType);
                            break;
                        case "Penalty":
                            successMatchType = ShowPopUp(invoiceLst, statementLst, false, "Penalty");
                            successMatchTypeList.Add(successMatchType);
                            break;
                    }
                }
            }
            else
            {
                lblAutoMatch.Text = "No records found for amount,reference,discount and penalty!";
                btnAutoMatchClickPopup.Show();
                return successMatchTypeList = null;
            }
            GetUnmatchedLists();
            return successMatchTypeList;
        }
    }
}